<!DOCTYPE html>
<html lang="zh">
	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<meta http-equiv="X-UA-Compatible" content="ie=edge">
		<title>贪吃蛇</title>
		<script src="../javascript/jquery-3.3.1.js" type="text/javascript" charset="utf-8"></script>
		<link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css"/>
		<style>
			*{
				padding: 0;
				margin: 0;
			}
			p{
				padding: 0;
				margin: 0;
			}
			.game-container{
				margin: 30px auto 0 auto;
				height: 521px;
				width: 521px;
				line-height: 0;
				background-color: aqua;
			}
			.game-container div{
				height: 25px;
				width: 25px;
				margin-top: 1px;
				margin-left: 1px;
				display: inline-block;
			}
			.game-block{
				background-color: antiquewhite;
			}
			.game-snake{
				background-color: blue;
			}
			.game-food{
				background-color: red;
			}
		</style>
		<style>
			.btns{
				width: 521px;
				margin: auto;
				margin-top: 30px;
			}
			.info{
				width: 521px;
				margin: auto;
				margin-top: 10px;
				font-size: 10px;
				color: #777777;
				text-align: center;
			}
			.btn{
				height: 50px;
			}
			.speed ,.score,.best{
				float: right;
				background-color: #5CB85C;
				width: 60px;
				height: 50px;
				display: inline-block;
				margin-left: 10px;
				text-align: center;
				border-radius: 8px;
			}
			#speed ,#score,#best{
				height: 30px;
				line-height: 30px;
				font-size: 20px;
			}
		</style>
	</head>
	<body>
		<div class="btns">
			<button type="button" class="btn btn-info" id="Start">Start</button>
			<button type="button" id="PlusSpeed" class="btn btn-warning">PlusSpeed</button>
			<button type="button" id="ReduceSpeed" class="btn btn-warning">ReduceSpeed</button>
			<div class="speed">
				<p>speed</p>
				<p id='speed'>10</p>
			</div>
			<div class="score">
				<p>score</p>
				<p id='score'>0</p>
			</div>
			<div class="best">
				<p>best</p>
				<p id='best'>0</p>
			</div>
		</div>
		<div class="info">
			<p>电脑端通过上下左右控制方向，手机端通过游戏主体界面的上下左右区域来控制方向</p>
		</div>
		<div class="game-container">
		</div>
		
		<script type="text/javascript">
			function controls(){//增加的界面和更多可控按钮
				$("#Start").click(()=>{
					if($("#Start").text()=="Restart"){
						Methods.restart(blocks,snake);
					}
					if(isStart){
						$("#Start").text("Start");
					}else{
						$("#Start").text("Stop");
					}
					isStart=!isStart;
				});
				$("#PlusSpeed").click(()=>{
					if(speed>50){
						speed-=50;
						$("#speed").text((new Number($("#speed").text()))+1);
					}
					
				});
				$("#ReduceSpeed").click(()=>{
					if(speed<1000){
						speed+=50;
						$("#speed").text((new Number($("#speed").text()))-1);
					}
				});
				 
			}
			
			function save(){
				if(typeof localStorage!=undefined){
					localStorage.setItem('RSbest',$("#best").text());
				}
			}
			function load(){
				if(typeof localStorage!=undefined){
					$("#best").text(localStorage.getItem('RSbest'));
				}
			}
		</script>
		<script type="text/javascript">
			function touch_control(e){//增加移动端操作方式
				e=e.changedTouches[0];
				var X=e.clientX-$('.game-container')[0].offsetLeft-521/2;
				var Y=e.clientY-$('.game-container')[0].offsetTop-521/2;
				if(X>260||Y>260){
					return;
				}
				if(X<-260||Y<-260){
					return;
				}
				var direction=0;
				if(X<=0){
					if(Y<=0){
						if(Y<X){
							direction='up';
						}else{
							direction='left';
						}
					}else{
						if(Y>0){
							if(Y<-X){
								direction='left';
							}else{
								direction='down';
							}
						}
					}
				}else if(X>0){
					if(Y<=0){
						if(-Y<X){
							direction='right';
						}else{
							direction='up';
						}
					}else{
						if(Y>0){
							if(Y<X){
								direction='right';
							}else{
								direction='down';
							}
						}
					}
				}
				if (direction == 'left' && snake.direction == 'right') {
					return;
				}
				if (direction == 'up' && snake.direction == 'down') {
					return;
				}
				if (direction == 'right' && snake.direction == 'left') {
					return;
				}
				if (direction == 'down' && snake.direction == 'up') {
					return;
				}
				snake.direction = direction;

			}
		</script>
		<script type="text/javascript">
			window.onload = () => {
				load();
				var maplength = 20;
				speed = 550;
				isStart=0;
				Methods = {
					restart(blocks,snake){
						for(var i in blocks){
							for(var k in blocks[i]){
								blocks[i][k].className='game-block';
							}
						}
						snake.body=[{
							x: 3,
							y: 0
						}, {
							x: 2,
							y: 0
						}, {
							x: 1,
							y: 0
						}, {
							x: 0,
							y: 0
						}];
						snake.IsDead=0;
						snake.direction= 'right';
						snake.display(blocks);
						isStart=1;
						movement = setInterval(movement_fun, speed);
						$("#score").text(0);
					},
					create() {
						var game_block = "<div class='game-block'></div>";
						for (var i = 0; i < maplength * maplength; i++) {
							$('.game-container')[0].innerHTML += game_block;
						}
						var arr = new Array();
						var blocks = $('.game-block');

						for (var i = 0; i < maplength; i++) {
							arr.push(new Array());
							for (var k = 0; k < maplength; k++) {
								arr[i].push(blocks[i * maplength + k]);
							}
						}
						return arr;
					},
					sleep(time) {
						var t = Date.now();
						while (Date.now() - t < time) {}
					},
					setFood(blocks, snake) {
						while (1) {
							var point = Math.round(Math.random() * 1000 % 400);
							point = {
								x: Math.floor(point % 20),
								y: Math.floor(point / 20)
							};
							var f = 0;
							snake.body.forEach(p => {
								if (point.x == p.x && point.y == p.y) {
									f = 1;
								}
							});
							if (f == 0) {
								return point;
							}
						}

					},
					displayFood(blocks) {
						blocks[food.y][food.x].className = "game-food";
					}
				};
				snake = {
					IsDead:0,
					body: [{
						x: 3,
						y: 0
					}, {
						x: 2,
						y: 0
					}, {
						x: 1,
						y: 0
					}, {
						x: 0,
						y: 0
					}],
					before: {
						x: 0,
						y: 0
					},
					direction: 'right',
					display(blocks) {
						if(blocks[this.body[0].y][this.body[0].x].className=='game-food'){
							this.add();
							food=Methods.setFood(blocks,snake);
						}
						blocks[this.before.y][this.before.x].className = 'game-block';
						for (var i in this.body) {
							blocks[this.body[i].y][this.body[i].x].className = 'game-snake';
						}
					},
					add() {
						var node = {
							x: this.body[1].x,
							y: this.body[1].y
						};
						this.body.push(node);
						$("#score").text((new Number($("#score").text()))+21-speed/50);
						var score=new Number($("#score").text());
						var best=new Number($("#best").text());
						if(score>best){
							$("#best").text(score);
							save();
						}
					},
					move() {
						var node = {
							x: 0,
							y: 0
						};
						switch (this.direction) {
							case 'right':
								node.x++;
								break;
							case 'left':
								node.x--;
								break;
							case 'up':
								node.y--;
								break;
							case 'down':
								node.y++;
								break;
						}
						this.before.x = this.body[this.body.length - 1].x;
						this.before.y = this.body[this.body.length - 1].y;
						for (var i = this.body.length - 1; i > 0; i--) {
							this.body[i].x = this.body[i - 1].x;
							this.body[i].y = this.body[i - 1].y;
						}
						this.body[0].x += node.x;
						this.body[0].y += node.y;
					},
					isDead() {
						if (this.body[0].x < 0 || this.body[0].x > maplength - 1) {
							return true;
						}
						if (this.body[0].y < 0 || this.body[0].y > maplength - 1) {
							return true;
						}
						for (var i = 1; i < this.body.length; i++) {
							if (this.body[0].x == this.body[i].x && this.body[0].y == this.body[i].y) {
								return true;
							}
						}
						return false;
					},

				};
				
				blocks = Methods.create();
				var food= Methods.setFood(blocks,snake)
				snake.display(blocks);
				window.ontouchstart=touch_control;
				window.onkeydown = event => {
					if (event.key == 'p' || event.key == 'P') {
						clearInterval(movement);
					}
					var direction = '';
					switch (event.key) {
						case 'ArrowLeft':
							direction = 'left';
							break;
						case 'ArrowUp':
							direction = 'up';
							break;
						case 'ArrowDown':
							direction = 'down';
							break;
						case 'ArrowRight':
							direction = 'right';
							break;
						case 'a':
							direction = 'left';
							break;
						case 'w':
							direction = 'up';
							break;
						case 's':
							direction = 'down';
							break;
						case 'd':
							direction = 'right';
							break;
						case 'A':
							direction = 'left';
							break;
						case 'W':
							direction = 'up';
							break;
						case 'S':
							direction = 'down';
							break;
						case 'D':
							direction = 'right';
							break;
					}
					if (direction == 'left' && snake.direction == 'right') {
						return;
					}
					if (direction == 'up' && snake.direction == 'down') {
						return;
					}
					if (direction == 'right' && snake.direction == 'left') {
						return;
					}
					if (direction == 'down' && snake.direction == 'up') {
						return;
					}
					snake.direction = direction;
				}			
				var beforeSpeed=speed;
				var movement_fun=function(){
					
					if(isStart){
						Methods.displayFood(blocks);
						snake.move();
						if (snake.isDead()) {
							snake.IsDead=1;
							$("#Start").text("Restart");
							clearInterval(movement);
						} else {
							snake.display(blocks);
						}
					}
					if(beforeSpeed!=speed){
						beforeSpeed=speed;
						clearInterval(movement);
						movement=setInterval(movement_fun,speed)
					}
				}
				movement = setInterval(movement_fun, speed)
				controls();
			};
		</script>
	</body>
</html>
